﻿using Lightworks.Core.Repository;
using Lightworks.Core.Service;
using Lightworks.System.Dto;
using Lightworks.System.Models;
using Microsoft.Extensions.Logging;
using SqlSugar;

namespace Lightworks.System.Services.Impl
{
    [Service]
    public class RoleService : IRoleService
    {
        SugarRepository<Role> repo;
        ILogger<RoleService> logger;
        SugarRepository<RoleRes> roleResRepo;

        public RoleService(SugarRepository<Role> repo, 
            SugarRepository<RoleRes> roleResRepo,
            ILogger<RoleService> logger) 
        {
            this.roleResRepo = roleResRepo;
            this.repo = repo;
            this.logger = logger;
        }

        public bool Delete(long id)
        {
            using (var ctx = repo.Context.CreateContext()) 
            {
                try
                {
                    if(ctx.Db.Queryable<UserRole>().Count(x => x.RoleId == id)>0)
                        return false;
                    ctx.Db.Deleteable<Role>().Where(x => x.Id == id).ExecuteCommand();
                    ctx.Db.Deleteable<RoleRes>().Where(x => x.RoleId == id).ExecuteCommand();
                    ctx.Commit();
                    return true;
                }catch (Exception ex) {
                    logger.LogError(ex.Message, ex);
                    return false;
                }
            }
        }

        public List<Role> GetAll()
        {
            return repo.GetList();
        }

        public long[] GetResIdByRoleId(long roleId)
        {
            return roleResRepo.AsQueryable()
                .Where(x=>x.RoleId == roleId)
                .Select(r=>r.ResourceId)
                .ToArray();
        }

        public PageData<Role> GetRoleList(SearchReq req)
        {
            PageData<Role> result = new PageData<Role>();
            var predicate = Expressionable.Create<Role>()
                .AndIF(!string.IsNullOrWhiteSpace(req.Keywords),
                    r => r.Name!.Contains(req.Keywords!) || r.Alias!.Contains(req.Keywords!));
            var pageMode = req.GetPageModel();   
            result.Rows= repo.GetPageList(predicate.ToExpression(), pageMode);
            result.Total = pageMode.TotalCount;    
            return result;
        }

        public bool Save(Role role)
        {
            try
            {
                return repo.InsertOrUpdate(role);
            }
            catch (Exception ex) 
            {
                logger.LogError(ex.Message, ex);
                return false;
            }
            
        }

        public bool SetResourceForRole(long roleId, long[] resourceIds)
        {
            using (var ctx = repo.Context.CreateContext())
            {
                try
                {
                    List<RoleRes> list = new List<RoleRes>();
                    foreach (var resId in resourceIds)
                    {
                        list.Add(new RoleRes
                        {
                            RoleId = roleId,
                            ResourceId = resId
                        });
                    }

                    ctx.Db.Deleteable<RoleRes>().Where(r => r.RoleId == roleId).ExecuteCommand();
                    ctx.Db.Insertable<RoleRes>(list).ExecuteCommand();
                    //tod: 更新数据权限，和控制台权限，下个版本支持
                    //var role = repo.GetById(roleId);
                    ctx.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    logger.LogError(ex.Message);
                    return false;
                }
            }
        }
    }
}
